<?php
namespace App\Services\Iot;

use GuzzleHttp\Client as HttpClient;
use Hyperf\Utils\Arr;
use Hyperf\Utils\Str;
use Hyperf\HttpMessage\Exception\HttpException;

/**
 * Created by PhpStorm.
 * User: liuta
 * Date: 2018/9/29
 * Time: 18:44
 */


class Client
{

    private static function getHeader()
    {
        return [
            'Authorization' => 'Basic ' . config('iot.authorization'),
        ];
    }

    private static function formatParams($params)
    {
        $nonceStr = Str::random(16);
        $params['app_id'] = config('iot.app_id');
        $params['version'] = config('iot.version');
        $params['nonce'] = $nonceStr;

        $params['sign'] = self::getSign($params);

        logger('iot query params', $params);

        return $params;
    }

    private static function getSign(array $params)
    {
        ksort($params);

        $str = self::buildQuery($params);

        $str .= '&key=' . config('iot.app_secret');

        logger('before md5 str ' . $str);

        return Str::upper(md5($str));
    }


    private static function buildQuery($params)
    {
        logger('iot params', $params);

        return collect($params)
            ->map(function ($value, $key) {
                return $key . '=' . $value;
            })
            ->values()
            ->implode('&');
    }


    public static function send($action, $params = [], $method = 'GET')
    {

        $params = self::formatParams($params);

        $requestUrl = config('iot.gateway_url') . $action;

        $httpClient = new HttpClient();

        switch (strtoupper($method))
        {
            case 'POST':
                $result = $httpClient->post($requestUrl, [
                    'headers'  => self::getHeader(),
                    'form_params' => $params,
                    'http_errors' => false,
                ]);

                logger('iot post', compact('params', 'requestUrl', 'method'));

                break;

            case 'GET':
                $requestUrl .= '?' . self::buildQuery($params);

                logger('iot get ', compact('params', 'requestUrl', 'method'));

                $result = $httpClient->get($requestUrl, [
                    'headers'  => self::getHeader(),
                    'http_errors' => false,
                ]);

                break;

            default:
                throw new HttpException(400, 'method invalid');
        }

        $result = (array) json_decode($result->getBody()->getContents(), true);
        logger('iot result', $result);

//        if($errorCode = Arr::get($result, 'error.code')) {
//            abort(400, Arr::get($result, 'error.msg'));
//        }

        if(Arr::get($result, 'result') != 1) {
//            abort(400, Arr::get($result, 'description'));

        }

        return Arr::get($result, 'payload');
    }

}
